
#include "bmp.h"
#include "lcd.h"
#include "DoublyLinkedList.h"
#include "touch.h"

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>

//显示一张bmp图片
int show_bmp( int x0, int y0, char * filename )
{
    //1.打开图片文件 
    int fd = open( filename, O_RDONLY );
    if( fd == -1 )
    {
        perror("open bmp error ");
        return -1;
    }

    //2.读取图片的数据 
        //读取 宽度、高度、色深 
        int width = 0;
        lseek( fd, 0x12, SEEK_SET );
        read( fd, &width, 4 );

        int height = 0;
        lseek( fd, 0x16, SEEK_SET );
        read( fd, &height, 4 );

        short depth = 0;
        lseek( fd, 0x1C, SEEK_SET );
        read( fd, &depth, 2 );

        //读取像素点的颜色数据
        int line_size = 0;      //一行实际的字节数
        int laizi = 0;          //填充的字节数 

        laizi = 4 - ( abs(width)*(depth/8) ) % 4 ;
        if( laizi == 4 )
        {
            laizi = 0;
        }

        //验证一下bmp图片的参数
        //printf("w = %d, h = %d, d = %d, laizi = %d\n", width, height, depth, laizi );

        //一行实际的字节数 = 有效的字节数 + 填充的字节数
        line_size = abs(width)*(depth/8) + laizi;

        //一次性把整个图像的像素点数据 全部读取处理 
        unsigned char buf[ abs(height) * line_size ];
        lseek( fd, 0x36, SEEK_SET );
        read( fd, buf, abs(height) * line_size );

    //3.显示 
    int i,j;
    int color;
    unsigned char a,r,g,b;
    int num = 0;

    for( j=0; j<abs(height); j++ )
    {
        for( i=0; i<abs(width); i++ )
        {
            //合成像素点的颜色值
            b = buf[num++];
            g = buf[num++];
            r = buf[num++];
            if( depth == 32 )
            {
                a = buf[num++];
            }
            else
            {
                a = 0;
            }
            color = (a<<24) | (r<<16) | (g<<8) | b;

            //画点 
            display_point(  width>0 ? i+x0 : abs(width)-1-i+x0 ,  
                            height>0 ? abs(height)-1-j+y0 : j+y0 ,
                            color );
        }

        num = num + laizi;      //跳过无效的填充数据
    }

    //4.关闭图片 
    close( fd );
}



//搜索指定目录下的所有的bmp图片，保存到一个双向链表中，
int get_bmp_name( char * path , DList * list )
{
    //1.打开目录 
    DIR * dir = opendir( path );
    if( dir == NULL )
    {
        perror("opendir error ");
        return -1;
    }

    //2.读取目录项
    struct dirent * d;
    while( d = readdir( dir ) )
    {
        //过滤 . 和 .. 目录 
        if( strcmp( d->d_name , "." ) == 0 || strcmp( d->d_name , ".." ) == 0 )
        {
            continue;
        }

        //3.合成路径名 ---> “路径/文件名”
        char pathname[128] = {0};
        strcpy( pathname, path );                       // 路径 
        if( pathname[ strlen(pathname)-1 ] != '/' )     
        {
            pathname[ strlen(pathname) ] = '/';         //  /
        }
        strcat( pathname, d->d_name );                  // 文件名


        if( d->d_type == DT_REG )   //普通文件 
        {
            //4.判断后缀名是否为.bmp 
            if( strcmp( pathname+(strlen(pathname)-4), ".bmp" ) == 0 )
            {
                //5.把图片的名字 添加到链表中 
                DNode * pnew = (DNode *)malloc( sizeof(DNode) );
                strcpy( pnew->data, pathname );
                pnew->next = NULL;
                pnew->prev = NULL;

                insert_node( list, pnew );

            }
        }
        else if( d->d_type == DT_DIR )  //子目录，则继续打开去读取
        {
            //递归 
            get_bmp_name( pathname, list );
        }
    }

    //6.关闭目录 
    closedir( dir );
}

//循环显示这个目录下的所有图片 
int Circle_show_bmp( char * path )
{
    //创建一个双向链表 
    DList * list = create_list();

    //搜索指定目录下的所有的bmp图片，并保存到链表中
    get_bmp_name( path, list );

    //首尾相连 ---> 循环链表
    list->last->next = list->first;
    list->first->prev = list->last;

    DNode * p = list->first;        //遍历指针
    while( 1 )
    {
        printf("bmp : %s\n", p->data );

        //显示bmp图片 
        show_bmp( 0, 0, p->data );

        //延时 
        //sleep( 2 );
        //p = p->next;    //下一张 

        //获取手指滑动的方向
        int fx = get_direction();

        if( fx == 1 || fx == 3 )
        {
            p = p->next;        //下一张
        }
        else if( fx == 2 || fx == 4 )
        {
            p = p->prev;        //上一张
        }
    }

    //销毁链表 
    list->last->next = NULL;
    destroy_list( list );
}

